<?php

namespace pmvc\util;

use Exception;

/**
 * A simple stack object that supports references.
 */
class Stack {

	private $stack = Array();

	/**
	 * Creates from an existing array.
	 * @param array $stack
	 */
	public function __construct(Array &$stack=Array()) {
		$this->stack = $stack;
	}

	/**
	 * Returns a copy of the top element.
	 */
	public function top() {
		$count = count($this->stack)-1;
		return ($count<0) ? false : $this->stack[count($this->stack)-1];
	}

	/**
	 * Returns a reference to the top element.
	 */
	public function &topRef() {
		$idx = count($this->stack)-1;
		if ($idx<0) {
			return false;
		}
		$value = &$this->stack[$idx];
		return $value;
	}

	/**
	 * Returns a copy of the bottom element.
	 */
	public function bottom() {
		return count($this->stack)>0 ? $this->stack[0] : false;
	}

	/**
	 * Returns a reference to the bottom element.
	 */
	public function &bottomRef() {
		if (count($this->stack)==0) {
			return false;
		}
		$value = &$this->stack[0];
		return $value;
	}

	public function push($value) {
		array_push($this->stack, $value);
	}

	public function pushRef(&$value) {
		$this->stack []= $value;
	}

	public function pop() {
		return array_pop($this->stack);
	}

	public function &popRef() {
		$idx = count($this->stack)-1;
		if ($idx==-1) {
			return false;
		}
		$value = &$this->stack[$idx];
		array_pop($this->stack);
		return $value;
	}

	public function shift() {
		return array_shift($this->stack);
	}

	public function &shiftRef() {
		if (count($this->stack)==0) {
			return false;
		}
		$value = &$this->stack[0];
		array_shift($this->stack);
		return $value;
	}

	public function clear() {
		$this->stack = Array();
	}

	public function size() {
		return count($this->stack);
	}
	
}

?>